package com.hq.stream;

import org.junit.Test;

import java.util.Objects;
import java.util.function.Function;

/**
 * 它代表的含义是“函数”，而函数经常是有输入输出的，因此它含有一个apply方法，包含一个输入与一个输出；
 * 除apply方法外，它还有compose与andThen及indentity三个方法，其使用见下述示例；
 * @author hq
 */
@SuppressWarnings("all")
public class FunctionTest {
    @Test
    public void applyTest(){
        Function<String, Integer> function = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.valueOf(s);
            }

            @Override
            public <V> Function<V, Integer> compose(Function<? super V, ? extends String> before) {
                Objects.requireNonNull(before);
                return (V v) -> apply(before.apply(v));
            }

            @Override
            public <V> Function<String, V> andThen(Function<? super Integer, ? extends V> after) {
                Objects.requireNonNull(after);
                return (String t) -> after.apply(apply(t));
            }
        };

        Function<Integer, Integer> f = s -> ++s;
        Function<Integer, Integer> g = s -> s * 2;

        // 下面表示在执行F时，先执行G，并且执行F时使用G的输出当作输入。
        // Integer a = g.apply(2);  System.out.println(f.apply(a));
        Integer a = g.apply(2);
        System.out.println(a); //4
        System.out.println(f.apply(a));  //5
        System.out.println(f.compose(g).apply(2));  //5

        System.out.println("===========");
        // 表示执行F的Apply后使用其返回的值当作输入再执行G的Apply；
        // Integer a1 = f.apply(2); System.out.println(g.apply(a1));
        Integer a1 = f.apply(2);
        System.out.println(a1);  //3
        System.out.println(g.apply(a1)); //6
        System.out.println(f.andThen(g).apply(2)); //6

        // identity方法会返回一个不进行任何处理的Function，即输出与输入值相等；
        System.out.println(Function.identity().apply("a"));
    }
}
